package top.raoqq.sky.web.controller;


import cn.hutool.core.util.IdUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import top.raoqq.sky.config.SkyConfig;
import top.raoqq.sky.constant.RedisCacheKeyConstant;
import top.raoqq.sky.constant.SkyConstant;
import top.raoqq.sky.context.GlobalContext;
import top.raoqq.sky.dto.CaptchaDTO;
import top.raoqq.sky.dto.LoginUserDTO;
import top.raoqq.sky.dto.MenuDTO;
import top.raoqq.sky.service.CommonService;
import top.raoqq.sky.service.ConfigService;
import top.raoqq.sky.util.RedisUtils;
import top.raoqq.sky.vo.LoginVO;
import top.raoqq.sky.vo.Result;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * @author 饶奇奇
 * @date 2023/8/3
 */
@RestController
@Api(tags = "登录")
@RequiredArgsConstructor
public class LoginController {
    /**
     * 登录地址
     */
    private static final String LOGIN_URL = "login";

    /**
     * 获取验证码地址
     */
    private static final String CAPTCHA_URL = "captcha";

    /**
     * 获取用户对应的所有路由
     */
    private static final String GET_INFO = "getLoginUserInfo";

    /**
     * 退出登录
     */
    private static final String LOGOUT = "logouts";

    private  final SkyConfig skyconfig;

    private final CommonService commonService;
    private final ConfigService configService;
    private final AuthenticationManager authenticationManager;
    private final RedisUtils redisUtil;

    @ApiOperation("获取验证码")
    @GetMapping(CAPTCHA_URL)
    public Result<CaptchaDTO> captcha() {
        return Result.success(commonService.genCaptcha());
    }

    @ApiOperation("登录接口")
    @PostMapping(LOGIN_URL)
    public Result<String> login(@RequestBody @Valid LoginVO loginVO) {
        boolean captchaEnable = configService.enableCaptcha();
        if (captchaEnable) {
            // 校验验证码
            commonService.validateCaptcha(loginVO.getUuid(), loginVO.getCode());
        }
        // 登录认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginVO.getUsername(), loginVO.getPassword());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        LoginUserDTO loginUserDTO = (LoginUserDTO)authenticate.getPrincipal();
        // 认证通过存入redis
        // 生成token
        String token = IdUtil.simpleUUID();
        String key = RedisCacheKeyConstant.LOGIN_USER + token;
        // 用户登录有效期
        redisUtil.setCache(key, loginUserDTO, skyconfig.getTokenExpire(), TimeUnit.MINUTES);
        // 清空上下文
        SecurityContextHolder.clearContext();
        return Result.success(token);
    }

    @ApiOperation("获取当前用户所有可访问的路由")
    @GetMapping(GET_INFO)
    public Result<Map<String, Object>> getInfo() {
        Map<String, Object> result = new HashMap<>(16);
        result.put("avatar", GlobalContext.getAvatar());
        result.put("nickname", GlobalContext.getNickname());
        result.put("routes", commonService.getRoutes(GlobalContext.getUsername()));
        return Result.success(result);
    }

    @ApiOperation("退出登录")
    @GetMapping(LOGOUT)
    public Result logout() {
       // 清空用户登录信息
       redisUtil.deleteCache(RedisCacheKeyConstant.LOGIN_USER + GlobalContext.getToken());
       return Result.success();
    }
}
